"""
Create by yy on 27/01/2022 16:45
"""
import json
import threading

import bs4
import xlwt
from bs4 import BeautifulSoup
from tool_yy import Thread, debug, curl_data, Helper, get_time_stamp, get_now_time_stamp
from xlwt import Worksheet

lock = threading.RLock()


class Tender(Helper, Thread):
    def __init__(self):
        super().__init__()
        self.host = "https://www.hsztbzx.com"
        self.time_format = "%Y-%m-%d %H:%M:%S"
        self.start_time = get_time_stamp("2020-01-01 00:00:00", self.time_format)
        self.end_time = get_time_stamp("2020-12-31 23:59:59", self.time_format)
        self.end_flag = False
        self.rows = 1
        self.region_list = [
            {
                'title': '市辖区',
                'code': '420201'
            },
            {
                'title': '黄石港区',
                'code': '420202'
            },
            {
                'title': '西塞山区',
                'code': '420203'
            },
            {
                'title': '下陆区',
                'code': '420204'
            },
            {
                'title': '黄石经济技术开发区, 铁山区',
                'code': '420206'
            },
            {
                'title': '阳新县',
                'code': '420222'
            },
            {
                'title': '大冶市',
                'code': '420281'
            }
        ]

    def run(self):
        """
        启动函数
        :return:
        """
        self.__start()

    def __start(self):
        """
        启动子方法
        :return:
        """
        for region in self.region_list:
            page = 1
            while True:
                if self.end_flag:
                    break
                project_data = self.get_project_list(page, region)
                page = page + 1
                if project_data['totalPageCount'] < page:
                    break
                self.start_thread(project_data['rows'], self.handle_project_list, is_test=False)

    def handle_project_list(self, item):
        """
        处理项目列表
        :param item:
        :return:
        """
        with self.auto_handle_exception():
            # 获取发布时间 并转为时间戳用于判断
            public_time = get_time_stamp(item['publishTime'], self.time_format)
            # 如果小于开始时间, 则直接结束整个抓取
            if self.start_time > public_time:
                self.end_flag = True
                return
            # 不在 开始时间和结束时间范围内,则结束
            if not (self.start_time <= public_time <= self.end_time):
                debug("不在时间范围")
                return
            # 判断进展, 如果不是公式阶段, 直接结束
            if item['projectProgress'] != 4:
                debug("未到公示阶段")
                return
            self.get_tender_detail(item)

    def get_tender_detail(self, item):
        """
        获取投标详情(curl抓取源数据)
        :param item:
        :return:
        """
        req_url = self.host + "/front/tradeinfo/detail?projectId={id}&busiCode=553"
        req_url = req_url.format(id=item['id'])
        # req_url = req_url.format(id="4bae6d9e90b34fc1b735f8cec84d4035")
        header = {
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko"
        }
        with self.auto_handle_exception(throw_exception_flag=True):
            data = curl_data(req_url, header=header,
                             referer="https://www.hsztbzx.com/front/project/list/9005002007")
            # with open("statics/spider/tender_detail.json", "wb") as f:
            #     f.write(data.encode("utf-8"))
            # with open("statics/spider/tender_detail.json", "rb") as f:
            #     data = f.read().decode("utf-8")
            tender_detail = json.loads(data)
            self.__get_tender_detail(tender_detail)

    def __get_tender_detail(self, tender_detail):
        """
        获取投标详情(写入excel)
        :param tender_detail:
        :return:
        """
        data = tender_detail['data']['content']
        data = data.replace("<h2", "<p")
        data = data.replace("/h2", "/p")
        data = data.replace("&nbsp;", "")
        soup = BeautifulSoup(data, 'html.parser')
        p_list = soup.find_all("p")
        # style0 = xlwt.easyxf('font: name Times New Roman, color-index red, bold on',
        #                      num_format_str='#,##0.00')
        # style1 = xlwt.easyxf(num_format_str='D-MMM-YY')
        wb = xlwt.Workbook()
        ws: Worksheet = wb.add_sheet('测试excel')
        ws.write(0, 0, "标题信息")
        ws.write(0, 1, "成交金额(万元)")
        ws.write(0, 2, "一级区域")
        ws.write(0, 3, "二级区域")
        ws.write(0, 4, "发布时间")
        ws.write(0, 5, "项目编号")
        ws.write(0, 6, "供应商")
        ws.write(0, 7, "发布人")
        ws.write(0, 8, "采购人")

        # 解析数据(需要加锁)
        lock.acquire()
        # 标题
        ws.write(self.rows, 0, tender_detail["data"]["projectName"])
        # 成交金额
        ws.write(self.rows, 1, self.__get_amount(p_list))
        # 一级区域
        ws.write(self.rows, 2, tender_detail["data"]["areaName"])
        # 二级区域
        ws.write(self.rows, 3, "二级区域懂不起")
        # 发布时间
        ws.write(self.rows, 4, tender_detail["data"]["publishTime"])
        # 项目编号
        ws.write(self.rows, 5, tender_detail["data"]["tenderProjectCode"])
        # 供应商
        ws.write(self.rows, 6, self.__get_merchant(p_list))
        # 发布人
        ws.write(self.rows, 7, tender_detail["data"]["createUser"])
        # 采购人
        ws.write(self.rows, 8, self.__get_buy_person(p_list))
        self.rows = self.rows + 1
        lock.release()
        wb.save("statics/excel/" + str(get_now_time_stamp()) + ".xls")

    def __get_buy_person(self, p_list: bs4.ResultSet) -> str:
        """
        获取采购人信息
        :param p_list:
        :return:
        """
        find_flag = False
        for v in p_list:
            with self.auto_handle_exception():
                text = v.get_text().strip()
                text = text.replace(" ", "")
                if find_flag:
                    if "名称：" in text:
                        result_list = text.split('：')
                        return result_list[1]
                    continue
                if "采购人信息" in text:
                    find_flag = True

        return ""

    def __get_merchant(self, p_list: bs4.ResultSet) -> str:
        """
        获取供应商 名
        :param p_list:
        :return:
        """
        for v in p_list:
            with self.auto_handle_exception():
                text = v.get_text().strip()
                if "供应商名称：" in text:
                    result_list = text.split('：')
                    return result_list[1]

        return ""

    def __get_amount(self, p_list: bs4.ResultSet) -> str:
        """
        获取成交金额(默认第一个)
        :param p_list:
        :return:
        """
        for v in p_list:
            with self.auto_handle_exception():
                text = v.get_text().strip()
                if "万元" in text:
                    result_list = text.split('：')
                    return result_list[1]

        for v in p_list:
            with self.auto_handle_exception():
                text = v.get_text().strip()
                if "元" in text:
                    result_list = text.split('：')
                    return result_list[1]

        return ""

    def get_project_list(self, page, region) -> dict:
        """
        获取项目列表
        :param page:
        :param region:
        :return:
        """
        req_url = self.host + "/front/project/list/9005002007/list"

        header = {
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko"
        }
        req_data = {
            "page": page,
            "date": "",
            "regionCode": region["code"],
            "industryTag": "",
            "tenderProjectType": ""
        }
        # method POST
        with self.auto_handle_exception():
            data = curl_data(req_url, value=req_data, header=header,
                             referer="https://www.hsztbzx.com/front/project/list/9005002007")
        # with open("statics/spider/project_list.json", "wb") as f:
        #     f.write(data.encode("utf-8"))
        project_data = {}
        # with open("statics/spider/project_list.json", "rb") as f:
        #     data = f.read().decode("utf-8")
        with self.auto_handle_exception():
            project_data = json.loads(data)

        return project_data
